package com.mzkj.wanjulaile.mobile.api.modules.account.service;

import com.mzkj.common.data.StatusCode;
import com.mzkj.common.utils.AccessTokenUtils;
import com.mzkj.common.utils.Collections3;
import com.mzkj.common.utils.DateUtils;
import com.mzkj.common.utils.StringUtils;
import com.mzkj.wanjulaile.mobile.api.common.entity.ResultEntity;
import com.mzkj.wanjulaile.mobile.api.common.service.BaseService;
import com.mzkj.wanjulaile.mobile.api.common.service.SendSMSService;
import com.mzkj.wanjulaile.mobile.api.common.service.ServiceException;
import com.mzkj.wanjulaile.mobile.api.modules.account.constant.Constant;
import com.mzkj.wanjulaile.mobile.api.modules.account.entity.Account;
import com.mzkj.wanjulaile.mobile.api.modules.account.entity.Baby;
import com.mzkj.wanjulaile.mobile.api.modules.account.entity.BuyVip;
import com.mzkj.wanjulaile.mobile.api.modules.account.mapper.AccountMapper;
import com.mzkj.wanjulaile.mobile.api.modules.account.mapper.BabyMapper;
import com.mzkj.wanjulaile.mobile.api.modules.account.mapper.BuyVipMapper;
import com.mzkj.wanjulaile.mobile.api.modules.account.mapper.VipCategoryMapper;
import com.mzkj.wanjulaile.mobile.api.modules.coupon.entity.AccountCoupon;
import com.mzkj.wanjulaile.mobile.api.modules.coupon.entity.Coupon;
import com.mzkj.wanjulaile.mobile.api.modules.coupon.mapper.AccountCouponMapper;
import com.mzkj.wanjulaile.mobile.api.modules.coupon.mapper.CouponMapper;
import com.mzkj.wanjulaile.mobile.api.modules.order.entity.Order;
import com.mzkj.wanjulaile.mobile.api.modules.order.entity.OrderToy;
import com.mzkj.wanjulaile.mobile.api.modules.order.mapper.OrderMapper;
import com.mzkj.wanjulaile.mobile.api.modules.order.mapper.OrderToyMapper;
import com.mzkj.wanjulaile.mobile.api.modules.session.entity.Session;
import com.mzkj.wanjulaile.mobile.api.modules.session.mapper.SessionMapper;
import com.mzkj.wanjulaile.mobile.api.modules.shoppingCart.entity.ShoppingCart;
import com.mzkj.wanjulaile.mobile.api.modules.shoppingCart.mapper.ShoppingCartMapper;
import com.mzkj.wanjulaile.mobile.api.modules.weChat.service.MallService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;

/**
 * accountService
 * Created by wangxw on 2016/12/12.
 */
@Service("accountService")
public class AccountServiceImpl extends BaseService implements AccountService {

    @Value("${access_token_expires:432000}")
    private long accessTokenExpires;
    @Value("${captcha_expires:120}")
    private long captchaExpireTime;
    @Value("${sms.default.templateId}")
    private String templateId;
    //绑定手机成功短信模板id
    @Value("${sms.bindCouponNotice.templateId}")
    private String bindCouponNoticeTemplateId;
    @Value("${mode.debug:false}")
    private boolean debug;
    @Autowired
    private AccountMapper accountMapper;
    @Autowired
    private SessionMapper sessionMapper;

    @Autowired
    private ShoppingCartMapper shoppingCartMapper;
    @Autowired
    private BuyVipMapper buyVipMapper;
    @Autowired
    private AccountCouponMapper accountCouponMapper;
    @Autowired
    private BabyMapper babyMapper;
    @Autowired
    private MallService mallService;
    @Autowired
    private CouponMapper couponMapper;
    @Autowired
    private OrderMapper orderMapper;
    @Autowired
    private OrderToyMapper orderToyMapper;
    @Autowired
    private SendSMSService sendSMSService;
    @Autowired
    private VipCategoryMapper vipCategoryMapper;

    @Override
    public Account getByPhone(String phone) {
        return accountMapper.getByPhone(phone);
    }

    @Override
    public Account getAccount(String id) {
        return accountMapper.get(id);
    }


    @Override
    public Account get2(String id) {
        Account account = accountMapper.get(id);
        if (account != null) {
            BuyVip buyVip = account.getCurBuyVip();
            if (buyVip != null) {
                account.setCurBuyVip(buyVipMapper.get(buyVip.getId()));
            }
        }
        return account;
    }

    @Override
    public ResultEntity<Account> getById(String id) {
        if (id == null) {
            return new ResultEntity<>(StatusCode.SC4000.getValue(), StatusCode.SC4000.getDesc());
        }
        ResultEntity<Account> resultEntity = new ResultEntity<>();
        Account account;
        try {
            account = accountMapper.getById(id);
            if (account != null) {
                setAccountInfo(account);
                resultEntity.setStatusCode(StatusCode.SC0.getValue());
                resultEntity.setMsg(StatusCode.SC0.getDesc());
                resultEntity.setData(account);
            } else {
                resultEntity.setStatusCode(StatusCode.SC1000.getValue());
                resultEntity.setMsg(StatusCode.SC1000.getDesc());
            }
        } catch (ServiceException e) {
            resultEntity.setStatusCode(StatusCode.SC4002.getValue());
            resultEntity.setMsg(StatusCode.SC4002.getDesc());
            logger.error(e.getMessage(), e);
        }
        return resultEntity;
    }

    @Override
    public ResultEntity<Account> get(String accessToken) {
        ResultEntity resultEntity;
        try {
            Session session = sessionMapper.findByAccessToken(accessToken);
            Account account = accountMapper.getById(session.getAccountId());

            if (account != null && !StringUtils.isEmpty(account.getId())) {
                setAccountInfo(account);
                resultEntity = new ResultEntity<>(StatusCode.SC0, account);
            } else {
                resultEntity = new ResultEntity<>(StatusCode.SC1000);
            }
        } catch (ServiceException e) {
            logger.error(e.getMessage(), e);
            resultEntity = new ResultEntity<>(StatusCode.SC5000);
        }
        return resultEntity;
    }

    private void setAccountInfo(Account account) {
        //购物车数量
        List<ShoppingCart> shoppingCartList = shoppingCartMapper.findList2ByAccountId(account.getId());
        account.setShoppingCartCount(Collections3.isEmpty(shoppingCartList) ? 0 : shoppingCartList.size());
        //优惠券列表
        AccountCoupon accountCoupon = new AccountCoupon();
        accountCoupon.setAccount(account);
        List<AccountCoupon> accountCouponList = accountCouponMapper.getCouponsByAccountId(accountCoupon);
        account.setAccountCouponList(accountCouponList);

        //宝宝信息
        List<Baby> babyList = babyMapper.getListByAccountId(account.getId());
        account.setBabies(babyList);
        //账户租赁玩具金额
        account.setToyFeeCount(getToyCount(account.getId()));

        //是否存在购买记录
        BuyVip buyVip = new BuyVip();
        buyVip.setAccount(account);
        List<BuyVip> buyVipList = buyVipMapper.hasBuy(buyVip);
        account.setHasBuy(buyVipList.size() > 0 ? true : false);

        calTotalDeposit(account);
        setAccountVipSpan(account);

        if (null != account.getVipType()) {
            account.setVipCategory(vipCategoryMapper.getByType(account.getVipType()));
        }
    }

    private void setAccountVipSpan(Account account1) {
        //设置VIP时段
        String vipSpan = "";
        if (StringUtils.isNotEmpty(account1.getVipStart()) && StringUtils.isNotEmpty(account1.getVipEnd())) {
            Date start = DateUtils.parseDate(account1.getVipStart());
            Date end = DateUtils.parseDate(account1.getVipEnd());
            Date dayAfter = DateUtils.getDayAfter(end, -1);
            String s = DateUtils.formatDate(dayAfter, "yyyy/MM/dd");
            if (end.compareTo(new Date()) > 0) {
                vipSpan = DateUtils.formatDate(DateUtils.parseDate(account1.getVipStart()), "yyyy/MM/dd") + "~" + s;
            } else {
                //有没有未使用状态的购买vip记录
                List<BuyVip> buyVipList = buyVipMapper.unUseBuyVip(account1.getId());
                if (Collections3.isEmpty(buyVipList)) {
                    vipSpan = "过期了";
                } else {
                    vipSpan = "待激活";
                }
            }
        } else if (account1.getVipType() != null && account1.getVipType() != 0) {
            vipSpan = "下单后显示";
        }
        account1.setVipSpan(vipSpan);
    }

    @Override
    public List<Account> findList() {
        return accountMapper.findList();
    }

    @Override
    public int update(Account account) {
        return accountMapper.update(account);
    }

    @Transactional
    public void calTotalDeposit(Account account) {
        account.setTotalDeposit(buyVipMapper.calDepositByAccountId(account.getId()));
    }

    /**
     * 根据unionID获取账户信息
     *
     * @param unionID
     * @return
     */
    @Override
    public Account getByUnionID(String unionID) {
        return accountMapper.getByUnionId(unionID);
    }

    

    private Integer getToyCount(String accountId) {
        Integer toyFeeCount = 0;
        Order search = new Order();
        search.setAccount(new Account(accountId));
        search.setPayStatus(1);
        List<Order> orderList = orderMapper.findListByAccountId2(search);
        if (!Collections3.isEmpty(orderList)) {
            for (Order order : orderList) {
                List<OrderToy> orderToyList = orderToyMapper.getListByOrderId(order.getId());
                for (OrderToy temp : orderToyList) {
                    toyFeeCount += (temp.getToy().getRetailPrice() == null ? temp.getToy().getMarketPrice() : temp.getToy().getRetailPrice());
                }
            }
        }
        return toyFeeCount;
    }

    private Session getSession(Account account) {
        //计算该账户总的押金(未退还的)存入totalDeposit字段
        account.setTotalDeposit(buyVipMapper.calDepositByAccountId(account.getId()));
        //设置宝宝信息
        account.setBabies(babyMapper.getListByAccountId(account.getId()));

        sessionMapper.deleteByAccount(account.getId());
        Session session = new Session();
        session.setAccountId(account.getId());
        session.setValid(1);
        session.setExpiresIn(accessTokenExpires);
        session.setClientType("web");
        StringBuilder sb = new StringBuilder();
        sb.append(session.getAccountId())
                .append(System.currentTimeMillis())
                .append(session.getClientType());
        session.setAccessToken(AccessTokenUtils.createToken(sb.toString()));
        sb.append("refresh_token");
        session.setRefreshToken(AccessTokenUtils.createToken(sb.toString()));
        Date nowDate = new Date();
        session.setCreateDate(nowDate);
        session.setUpdateDate(nowDate);
        sessionMapper.insert(session);
        return session;
    }

    //发放优惠券并短信通知
    private void sendCoupon(Account accountData) {
        Coupon coupon = new Coupon();
        coupon.setCouponType(Coupon.COUPON_TYPE_ACCOUNT);
        List<Coupon> couponList = couponMapper.getCouponByType(coupon);
        if (!Collections3.isEmpty(couponList)) {
            for (Coupon coupon1 : couponList) {
                AccountCoupon accountCoupon = new AccountCoupon();
                accountCoupon.setAccount(accountData);
                accountCoupon.setCoupon(coupon1);
                accountCoupon.setCount(1);
                Date date1 = DateUtils.parseDate(DateUtils.formatDate(new Date(), "yyyy/MM/dd"));
                accountCoupon.setCreateDate(date1);
                accountCoupon.setUpdateDate(date1);
                if (!StringUtils.isEmpty(coupon1.getPeriodValidity())) {
                    accountCoupon.setExpireDate(DateUtils.addDays(DateUtils.getTodayZero(), Integer.valueOf(coupon1.getPeriodValidity())));
                }
                accountCouponMapper.insert(accountCoupon);
            }
            //绑定成功 发送短信
            sendSMSService.sendSMS(accountData.getPhone(), new String[]{couponList.size() + ""}, bindCouponNoticeTemplateId);
        }
    }

    /**
     * 更新用户自定义昵称
     *
     * @param account
     */
    @Override
    @Transactional
    public void updateAccountNick(Account account) {
        accountMapper.updateAccountNick(account);
    }

    /**
     * 更新用户自定义头像
     *
     * @param account
     */
    @Override
    @Transactional
    public void updateAccountImg(Account account) {
        accountMapper.updateAccountImg(account);
    }

    @Override
    public Account getDetailInfoByAccountId(String accountId) {
        Account account = accountMapper.get(accountId);
        setAccountInfo(account);
        return account;
    }

    @Override
    public Account getAccountByAccessToken(String accessToken) {
        Session session = sessionMapper.findByAccessToken(accessToken);
        return accountMapper.getById(session.getAccountId());
    }

    public Account findAccountByOpenid(String openid) {
        Account account = accountMapper.findAccountByOpenid(openid);
        if (account != null && account.getVipType().equals(Constant.WAN_MEMBER)) {
            List<ShoppingCart> carts = shoppingCartMapper.findList2ByAccountId(account.getId());
            account.setCartCount(Collections3.isEmpty(carts) ? 0 : carts.size());
            if (null != account.getVipType()){
//                setAccountStar(account);
            }
        }
        return account;
    }
}
